import 'cool_ui.dart';
import 'package:flutter/material.dart';

class SafeKeyboardDemo extends StatefulWidget {
  final KeyboardController controller;
  SafeKeyboardDemo({Key key, this.controller}) : super(key: key);
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return SafeKeyboard(controller: controller);
  }
}

double divide = 8;

class SafeKeyboard extends State<SafeKeyboardDemo> {
  static const CKTextInputType inputType = const CKTextInputType(name: 'CKTestKeyboard');
  static double getHeight(BuildContext ctx) {
    MediaQueryData mediaQuery = MediaQuery.of(ctx);
    final size = mediaQuery.size;
    w = ((size.width + divide) / 10);
    h = size.width > size.height ? size.height/(3 * 5) : w * 1.2;
    return h * 5;
  }

  final KeyboardController controller;
  SafeKeyboard({this.controller});
  bool isCaps = false;
  int type = 0;
  static double w = 0;
  static double h = 0;
  bool showKey = false;
  OverlayEntry overlayEntry;
  String currentChar = '';
  double left = 0;
  double top = 0;

  static register() {
    CoolKeyboard.addKeyboard(
        SafeKeyboard.inputType,
        KeyboardConfig(
            builder: (context, controller, params) {
              controller.isPassword = true;
              controller.passwordChar = '*';
              return SafeKeyboardDemo(controller: controller);
            },
            getHeight: SafeKeyboard.getHeight));
  }

  @override
  Widget build(BuildContext context) {
    MediaQueryData mediaQuery = MediaQuery.of(context);
    return Material(
        child: Overlay(
      initialEntries: [
        OverlayEntry(builder: (ctx) {
          return DefaultTextStyle(
              style: TextStyle(fontWeight: FontWeight.w500, color: Colors.black, fontSize: 23.0),
              child: Container(
                  height: getHeight(context),
                  width: mediaQuery.size.width,
                  decoration: BoxDecoration(
                    color: Color(0xFFE2E2E2),
                  ),
                  child: Column(
                    children: [
                      Row(
                        children: [
                          Visibility(
                              visible: type != 1,
                              child: InkWell(
                                child: Container(height: h, width: w, alignment: Alignment.center, child: Text('符', style: TextStyle(color: Colors.blue))),
                                onTap: () {
                                  setState(() {
                                    type = 1;
                                  });
                                },
                              )),
                          Visibility(
                              visible: type != 2,
                              child: InkWell(
                                child: Container(height: h, width: w, alignment: Alignment.center, child: Text('123', style: TextStyle(color: Colors.blue))),
                                onTap: () {
                                  setState(() {
                                    type = 2;
                                  });
                                },
                              )),
                          Visibility(
                              visible: type != 0,
                              child: InkWell(
                                child: Container(height: h, width: w, alignment: Alignment.center, child: Text('Abc', style: TextStyle(color: Colors.blue))),
                                onTap: () {
                                  setState(() {
                                    type = 0;
                                  });
                                },
                              )),
                          InkWell(
                            child: Container(
                                height: h,
                                width: w,
                                alignment: Alignment.center,
                                child: Icon(
                                  showKey ? Icons.visibility : Icons.visibility_off,
                                  color: showKey ? Colors.blue : Colors.grey,
                                )),
                            onTap: () {
                              setState(() {
                                showKey = !showKey;
                              });
                            },
                          ),
                          Expanded(
                            child: Container(
                              child: Text(
                                '安全键盘',
                                style: TextStyle(color: Colors.grey),
                              ),
                              alignment: Alignment.center,
                            ),
                          ),
                          InkWell(
                            child: Container(height: h, width: w + 10, alignment: Alignment.center, child: Text('完成', style: TextStyle(color: Colors.blue))),
                            onTap: () {
                              controller.doneAction();
                            },
                          )
                        ],
                      ),
                      SizedBox(
                        height: divide / 2,
                      ),
                      type == 0
                          ? Column(
                              children: [
                                Row(
                                  children: (List.generate(9, (index) => '${index + 1}')..add('0')).map((e) => buildButton(e)).toList(),
                                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                ),
                                SizedBox(
                                  height: divide,
                                ),
                                Row(
                                  children: ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'].map((e) => buildButton(e)).toList(),
                                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                ),
                                SizedBox(
                                  height: divide,
                                ),
                                Row(
                                  children: ['caps', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l']
                                      .map((e) => e == 'caps'
                                          ? Container(
                                              decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                                              child: GestureDetector(
                                                behavior: HitTestBehavior.translucent,
                                                child: Container(
                                                  width: w - divide,
                                                  height: h - divide,
                                                  child: Icon(
                                                    Icons.keyboard_capslock,
                                                    color: isCaps ? Colors.blue : Colors.black,
                                                  ),
                                                  alignment: Alignment.center,
                                                ),
                                                onTap: () {
                                                  setState(() {
                                                    isCaps = !isCaps;
                                                  });
                                                },
                                              ),
                                            )
                                          : buildButton(e))
                                      .toList(),
                                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                ),
                                SizedBox(
                                  height: divide,
                                ),
                                Row(
                                  children: ['space', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'delete'].map((e) {
                                    if (e == 'space') {
                                      return Container(
                                        decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                                        child: GestureDetector(
                                          behavior: HitTestBehavior.translucent,
                                          child: Container(
                                            width: w - divide + w / 2,
                                            height: h - divide,
                                            child: Icon(Icons.space_bar),
                                            alignment: Alignment.center,
                                          ),
                                          onTap: () {
                                            controller.addText(' ');
                                          },
                                        ),
                                      );
                                    } else if (e == 'delete') {
                                      return Container(
                                        decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                                        child: GestureDetector(
                                          behavior: HitTestBehavior.translucent,
                                          child: Container(
                                            width: w - divide + w / 2,
                                            height: h - divide,
                                            child: Icon(Icons.backspace),
                                            alignment: Alignment.center,
                                          ),
                                          onTap: () {
                                            controller.deleteOne();
                                          },
                                        ),
                                      );
                                    } else {
                                      return buildButton(e);
                                    }
                                  }).toList(),
                                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                )
                              ],
                            )
                          : type == 1
                              ? Column(children: [
                                  Row(
                                    children: ['&', '"', ';', '^', ',', '|', '\$', '*', ':', '\''].map((e) => buildButton(e)).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  ),
                                  SizedBox(
                                    height: divide,
                                  ),
                                  Row(
                                    children: ['?', '{', '[', '~', '#', '}', '.', ']', '\\', '!'].map((e) => buildButton(e)).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  ),
                                  SizedBox(
                                    height: divide,
                                  ),
                                  Row(
                                    children: ['(', '%', '-', '_', '+', '/', ')', '=', '<', '`'].map((e) => buildButton(e)).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  ),
                                  SizedBox(
                                    height: divide,
                                  ),
                                  Row(
                                    children: ['>', '@', 'space', 'delete'].map((e) {
                                      if (e == 'space') {
                                        return Container(
                                          decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                                          child: GestureDetector(
                                            behavior: HitTestBehavior.translucent,
                                            child: Container(
                                              width: w - divide + w * 5.5,
                                              height: h - divide,
                                              child: Icon(Icons.space_bar),
                                              alignment: Alignment.center,
                                            ),
                                            onTap: () {
                                              controller.addText(' ');
                                            },
                                          ),
                                        );
                                      } else if (e == 'delete') {
                                        return Container(
                                          decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                                          child: GestureDetector(
                                            behavior: HitTestBehavior.translucent,
                                            child: Container(
                                              width: w - divide + w / 2,
                                              height: h - divide,
                                              child: Icon(Icons.backspace),
                                              alignment: Alignment.center,
                                            ),
                                            onTap: () {
                                              controller.deleteOne();
                                            },
                                          ),
                                        );
                                      } else {
                                        return buildButton(e);
                                      }
                                    }).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  )
                                ])
                              : Column(children: [
                                  Row(
                                    children:
                                        ['1', '2', '3'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  ),
                                  SizedBox(
                                    height: divide,
                                  ),
                                  Row(
                                    children:
                                        ['4', '5', '6'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  ),
                                  SizedBox(
                                    height: divide,
                                  ),
                                  Row(
                                    children:
                                        ['7', '8', '9'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList(),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  ),
                                  SizedBox(
                                    height: divide,
                                  ),
                                  Row(
                                    children: ['.', '0'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList()
                                      ..add(Container(
                                        decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                                        child: GestureDetector(
                                          behavior: HitTestBehavior.translucent,
                                          child: Container(
                                            width: (MediaQuery.of(context).size.width - divide * 2) / 3,
                                            height: h - divide,
                                            child: Icon(Icons.backspace),
                                            alignment: Alignment.center,
                                          ),
                                          onTap: () {
                                            controller.deleteOne();
                                          },
                                        ),
                                      )),
                                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                  )
                                ])
                    ],
                  )));
        }),
        OverlayEntry(
          builder: (ctx) {
            return left == 0 && top == 0
                ? Container()
                : Positioned(
                    left: left,
                    top: top,
                    child: Material(
                      child: Container(
                        width: (w - divide) * 1.2,
                        height: h,
                        alignment: Alignment.center,
                        padding: EdgeInsets.all(5),
                        child: Text(
                          currentChar,
                          style: TextStyle(color: Colors.white, fontSize: 30, fontWeight: FontWeight.bold),
                        ),
                        color: Colors.black54,
                      ),
                    ),
                  );
          },
        )
      ],
    ));
  }

  Widget buildButton(String title, {String value, double offsetWidth = 0.0, double customWidth}) {
    GlobalKey anchorKey = GlobalKey();
    if (isCaps) {
      title = title.toUpperCase();
    } else {
      title = title.toLowerCase();
    }
    if (value == null) {
      value = title;
    }
    return Container(
      key: anchorKey,
      decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
      child: Listener(
        behavior: HitTestBehavior.translucent,
        child: Container(
          width: customWidth == null ? w - divide + offsetWidth : customWidth,
          height: h - divide,
          child: Text(title),
          alignment: Alignment.center,
        ),
        onPointerDown: (e) {
          if (showKey) {
            RenderBox renderBox = anchorKey.currentContext.findRenderObject();
            var offset = renderBox.localToGlobal(Offset.zero);
            setState(() {
              currentChar = value;
              left = offset.dx - w * 0.1;
              top = offset.dy - h * 1.2 - (MediaQuery.of(anchorKey.currentContext).size.height - getHeight(anchorKey.currentContext));
            });
          }
          controller.addText(value);
        },
        onPointerUp: (e) {
          if (showKey) {
            setState(() {
              left = 0;
              top = 0;
            });
          }
        },
      ),
    );
  }
}
